package com.bw.skinfilecreator;

import com.bw.skinfilecreator.bean.ProjectConfigEntity;
import com.bw.skinfilecreator.bean.UtilConfigEntity;
import com.bw.skinfilecreator.utils.CompressedResourceUtils;
import com.bw.skinfilecreator.utils.FileUtils;
import com.bw.skinfilecreator.utils.XxSKinUtil;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.stage.DirectoryChooser;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.bw.skinfilecreator.utils.XxSKinUtil.*;


public class CreatorController {

    @FXML
    private VBox loading;

    @FXML
    private CheckBox option1;

    @FXML
    private CheckBox option2;

    @FXML
    private CheckBox option3;


    @FXML
    private TextArea logTextArea;

    @FXML
    private Button btnCreate;

    @FXML
    private Button btnEdit;
    @FXML
    private Button btnDel;
    @FXML
    private Button btnCreateFile;
    @FXML
    private Button btnDoChoose;
    private Stage dialogStage;
    @FXML
    private ComboBox<String> choiceBox;
    private ProjectConfigEntity projectConfigEntity;
    private Map<String, ProjectConfigEntity> projectConfigEntityMap;
    private XxSKinUtil xxSKinUtil;

    public void initialize() {
        btnEdit.setDisable(true);
        btnDel.setDisable(true);
        btnCreateFile.setDisable(true);
        btnDoChoose.setDisable(true);

        log("缓存目录:" + getCacheDirPath());
        checkZip();
        loadUtilCache();
        loadProjectConfig();
    }

    private void checkZip() {
        //解压皮肤工程到缓存目录
        // 解压资源中的data.zip到目标目录
        new CompressedResourceUtils().extractZipResource("/assets/SkinFactory.zip", getCacheDirPath(), this::log);
    }


    @FXML
    private void handleNewProjectConfigButtonAction(ActionEvent event) {
        //弹出新建配置弹窗
        showCustomDialog(null);
    }


    @FXML
    private void handleDoChooseButtonAction(ActionEvent event) {
        //判断是否有皮肤包
        String outFileDir = getSkinProjectCachePath() + "\\app\\build\\outputs\\apk\\release\\";

        File file = new File(outFileDir);
        if (!file.exists()) {
            log("未发现皮肤包文件");
            return;
        }
        //执行后续操作
        if (xxSKinUtil != null) {
            new Thread(() -> {
                try {
                    xxSKinUtil.onAfterMakeSkin();
                } catch (IOException e) {
                    log(e.getMessage());
                }
            }).start();
        }
    }

    @FXML
    private void handleEditProjectConfigButtonAction(ActionEvent event) {
        //弹出新建配置弹窗
        ProjectConfigEntity projectConfigEntity = null;
        if (projectConfigEntityMap != null) {
            projectConfigEntity = projectConfigEntityMap.get(choiceBox.getValue());
        }
        showCustomDialog(projectConfigEntity);
    }

    @FXML
    private void handleDelProjectConfigButtonAction(ActionEvent event) {
        //删除当前选中配置
        delProjectConfig(choiceBox.getValue());
    }

    private void showCustomDialog(ProjectConfigEntity projectConfigEntity) {
        // 创建对话框
        Dialog<Void> dialog = new Dialog<>();
        dialog.setTitle("项目配置");

        try {
            // 加载自定义布局
            FXMLLoader loader = new FXMLLoader(getClass().getResource("dialog_new_project_config.fxml"));
            dialog.getDialogPane().setContent(loader.load());
            ProjectConfigController dialogController = loader.getController();
            dialogController.initData(projectConfigEntity); // 传递数据到弹窗
            // 获取弹窗的Stage对象
            Stage dialogStage = (Stage) dialog.getDialogPane().getScene().getWindow();
            dialogController.setOnProjectActionListener(new ProjectConfigController.OnLiProjectActionListener() {
                @Override
                public void onSaveClick(ProjectConfigEntity projectConfigEntity) {

                    dialogStage.close();

                    //选择当前的配置
                    CreatorController.this.projectConfigEntity = projectConfigEntity;

                    //新增时追加选项
                    if (projectConfigEntityMap == null || !projectConfigEntityMap.containsKey(projectConfigEntity.getProjectName())) {
                        choiceBox.getItems().add(projectConfigEntity.getProjectName());
                        choiceBox.getItems().sort(String::compareTo);
                    }
                    choiceBox.setValue(projectConfigEntity.getProjectName());
                    btnEdit.setDisable(false);
                    btnDel.setDisable(false);
                    btnCreateFile.setDisable(false);
                    saveProjectConfig(projectConfigEntity);
                }

                @Override
                public void onCancelClick() {
                    dialogStage.close();
                }

                @Override
                public void onLog(String msg) {
                    log(msg);
                }
            });


            // 监听窗口关闭请求（点击“X”时触发）
            dialogStage.setOnCloseRequest((WindowEvent event) -> {
                // 在这里添加关闭前的逻辑（如确认是否关闭）
                // 若允许关闭，无需处理；若禁止关闭，调用event.consume()

            });
            // 显示对话框
            dialog.showAndWait();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    private void saveProjectConfig(ProjectConfigEntity projectConfigEntity) {
        if (projectConfigEntityMap == null) {
            projectConfigEntityMap = new HashMap<>();
        }
        //覆盖去重
        projectConfigEntityMap.put(projectConfigEntity.getProjectName(), projectConfigEntity);
        saveProjectConfigs2File();
    }

    /**
     * 删除配置
     *
     * @param projectName 项目名称
     */
    private void delProjectConfig(String projectName) {
        if (projectConfigEntityMap == null) return;
        projectConfigEntityMap.remove(projectName);

        saveProjectConfigs2File();

        choiceBox.getItems().remove(projectName);
        try {
            choiceBox.setValue(!choiceBox.getItems().isEmpty() ? choiceBox.getItems().get(0) : "");
            btnEdit.setDisable(choiceBox.getItems().isEmpty());
            btnDel.setDisable(choiceBox.getItems().isEmpty());
            btnCreateFile.setDisable(choiceBox.getItems().isEmpty());

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void saveProjectConfigs2File() {
        if (projectConfigEntityMap == null) return;
        //保存数据到本地
        File file = new File(getProjectCachePath());
        FileUtils.createFileByDeleteOldFile(file);
        //将列表写入文件
        try {
            PrintWriter printWriter = new PrintWriter(file, StandardCharsets.UTF_8);
            printWriter.print(new Gson().toJson(new ArrayList<>(projectConfigEntityMap.values())));
            printWriter.close();
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private void chooseDirectory(TextField textField, String title) {
        DirectoryChooser directoryChooser = new DirectoryChooser();
        directoryChooser.setTitle(title);
        //设置初始目录
        File initialDirectory = new File(textField.getText());

        //目录不存在使用默认用户目录
        if (!initialDirectory.exists() || !initialDirectory.isDirectory()) {
            initialDirectory = new File(System.getProperty("user.home"));
        }

        directoryChooser.setInitialDirectory(initialDirectory);

        File selectedDirectory = directoryChooser.showDialog(dialogStage);

        if (selectedDirectory != null) {
            textField.setText(selectedDirectory.getAbsolutePath());
            logTextArea.appendText("已选择: " + selectedDirectory.getAbsolutePath() + "\n");

            btnCreateFile.setDisable(choiceBox.getItems().isEmpty());
        }
    }

    @FXML
    private void handleHelpButtonAction(ActionEvent event) {
        //打开使用说明弹窗
        showClosableNoneAlert();
    }

    public void showClosableNoneAlert() {
        Alert alert = new Alert(Alert.AlertType.NONE);
        alert.setTitle("使用说明");
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("【注意事项】");
        stringBuilder.append("\n");
        stringBuilder.append("需配置系统环境变量 ANDROID_HOME 对应AndroidSDK目录，用以自动修正皮肤工程中的sdK配置");
        stringBuilder.append("\n");
        stringBuilder.append("【项目配置】");
        stringBuilder.append("\n");
        stringBuilder.append("  项目名称：区分不同的配置，相同名称会覆盖旧的配置");
        stringBuilder.append("\n");
        stringBuilder.append("  示例：F515系列SystemUI");
        stringBuilder.append("\n");
        stringBuilder.append("  皮肤资源路径：选择res资源目录的父目录");
        stringBuilder.append("\n");
        stringBuilder.append("  示例： ..\\skin_temp\\systemui_skin\\src\\main");
        stringBuilder.append("\n");
        stringBuilder.append("  Git上传路径：选择本地上传该皮肤包的仓库路径");
        stringBuilder.append("\n");
        stringBuilder.append("  示例: D:\\BWProject\\bw_skin\\SERES\\skinbags");
        stringBuilder.append("\n");
        stringBuilder.append("  分支名称: 对应皮肤仓库要提交推送的分支");
        stringBuilder.append("  皮肤包名称：自动重命名文件");
        alert.setContentText(stringBuilder.toString());
        // 获取弹窗的Stage对象
        Stage dialogStage = (Stage) alert.getDialogPane().getScene().getWindow();

        // 监听窗口关闭请求（点击“X”时触发）
        dialogStage.setOnCloseRequest((WindowEvent event) -> {
            // 在这里添加关闭前的逻辑（如确认是否关闭）
            // 若允许关闭，无需处理；若禁止关闭，调用event.consume()

        });

        alert.show();
    }

    @FXML
    private void handleExecuteButtonAction(ActionEvent event) {
        runTask(false);
    }


    public void handleCreateAndDoChooseButtonAction(ActionEvent actionEvent) {
        runTask(true);
    }

    private String getTimeNow() {
        long currentTimeMillis = System.currentTimeMillis();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("hh:mm:ss:SSS");
        return "[" + simpleDateFormat.format(new Date(currentTimeMillis)) + "] ";
    }

    private void log(String log) {
        logTextArea.appendText(getTimeNow() + log);
        logTextArea.appendText("\n");
    }

    /**
     * 加载项目配置
     */
    private void loadProjectConfig() {
        File file = new File(getProjectCachePath());
        if (file.exists()) {
            //文件存在，读取配置
            try {
                FileReader fileReader = new FileReader(file, StandardCharsets.UTF_8);
                if (projectConfigEntityMap == null) {
                    projectConfigEntityMap = new HashMap<>();
                }
                List<ProjectConfigEntity> projectConfigEntities = new Gson().fromJson(fileReader, new TypeToken<ArrayList<ProjectConfigEntity>>() {
                }.getType());
                List<String> chooses = new ArrayList<>();
                projectConfigEntities.sort(Comparator.comparing(ProjectConfigEntity::getProjectName));
                for (ProjectConfigEntity entity : projectConfigEntities) {
                    projectConfigEntityMap.put(entity.getProjectName(), entity);
                    chooses.add(entity.getProjectName());
                }
                choiceBox.getItems().addAll(chooses);
                choiceBox.getItems().sort(String::compareTo);
                choiceBox.setValue(!projectConfigEntityMap.isEmpty() ? choiceBox.getItems().get(0) : "");

                btnEdit.setDisable(projectConfigEntityMap.isEmpty());
                btnDel.setDisable(projectConfigEntityMap.isEmpty());
                btnCreateFile.setDisable(projectConfigEntityMap.isEmpty());

                log("加载项目配置完成");
            } catch (FileNotFoundException e) {
                throw new RuntimeException(e);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

    private void loadUtilCache() {
        File file = new File(getUtilCachePath());
        if (file.exists()) {
            //文件存在，读取配置
            try {
                FileReader fileReader = new FileReader(file, StandardCharsets.UTF_8);
                UtilConfigEntity utilConfigEntity = new Gson().fromJson(fileReader, UtilConfigEntity.class);
                if (utilConfigEntity == null) return;
                //文件夹选择
                choiceBox.setValue(utilConfigEntity.getProjectConfigEntity().getProjectName());
                btnEdit.setDisable(choiceBox.getValue().isEmpty());
                btnDel.setDisable(choiceBox.getValue().isEmpty());
                btnCreateFile.setDisable(choiceBox.getValue().isEmpty());

                //功能选项
                option1.setSelected(utilConfigEntity.isNeedOpenExplore());
                option2.setSelected(utilConfigEntity.isNeedPushToDevice());
                option3.setSelected(utilConfigEntity.isNeedPushToGit());


                log("加载工具配置完成");
            } catch (FileNotFoundException e) {
                throw new RuntimeException(e);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

    private void runTask(boolean runAfterTask) {
        logTextArea.clear();

        new Thread(() -> {
            xxSKinUtil = new XxSKinUtil(new UtilConfigProvider() {
                @Override
                public String getSkinProjectPath() {
                    return getSkinProjectCachePath();
                }

                @Override
                public ProjectConfigEntity getProject() {
                    if (projectConfigEntityMap != null && !projectConfigEntityMap.isEmpty()) {
                        return projectConfigEntityMap.get(choiceBox.getValue());
                    }
                    return null;
                }

                @Override
                public int launchType() {
                    int result = 0;
                    if (option1.isSelected()) {
                        result |= TYPE_OPEN_EXPLORE;
                    }

                    if (option2.isSelected()) {
                        result |= TYPE_PUSH_TO_DEVICE;
                    }

                    if (option3.isSelected()) {
                        result |= TYPE_REPLACE_TO_GIT;
                    }
                    return result;
                }

                @Override
                public void onLog(String msg) {
                    Platform.runLater(() -> log(msg));
                }

                @Override
                public void onCreateSkinFileSuccess() {
                    Platform.runLater(() -> {
                        btnDoChoose.setDisable(false);
                    });
                }

                @Override
                public void onLoadingStart() {
                    Platform.runLater(() -> loading.setVisible(true));
                }

                @Override
                public void onLoadingEnd() {
                    Platform.runLater(() -> loading.setVisible(false));
                }
            });
            Platform.runLater(() -> btnDoChoose.setDisable(true));
            xxSKinUtil.launch(runAfterTask);

        }).start();
    }
}